﻿/// <reference path="../Repeater/Repeater.js" />
/// <reference path="../Repeater/RepeaterDisplay.js" />
/// <reference path="Grouping.js" />
/// <reference path="Group.js" />
/// <reference path="../Enums/GroupedPagingMode.js" />

var $GroupedRepeater = TA.Turbo.Controls.GroupedRepeater = function GroupedRepeater(clientId)
{
	this.Repeater(clientId);
}
$GroupedRepeater.Inherit(TA.Turbo.Controls.Repeater);
$GroupedRepeater.Inherit(TA.Turbo.Controls.BaseGroupedRepeaterGroupContainer);

var ____a;
if (____a)
{
	$GroupedRepeater = new TA.Turbo.Controls.Repeater;
	$GroupedRepeater.prototype.Repeater = new TA.Turbo.Controls.Repeater();

	$GroupedRepeater.prototype._groups = new $RepeaterGroupingCollection();
	$GroupedRepeater.prototype._groupContainers = new Array();


	$GroupedRepeater.prototype.get_Groupings = function get_Groupings() { return new $RepeaterGroupingCollection(); }
	$GroupedRepeater.prototype.set_Groupings = function set_Groupings(value) { }

	$GroupedRepeater.prototype.get_GroupedPaging = function get_GroupedPaging() { return GroupedPagingMode.PageEntriesThenGroup; }
	$GroupedRepeater.prototype.set_GroupedPaging = function set_GroupedPaging(value) { }
	
}

$PropertyDefinition.Define($GroupedRepeater, "GroupedPaging", "GP", GroupedPagingMode.PageEntriesThenGroup);
$PropertyDefinition.Define($GroupedRepeater, "Groupings", "G", new $RepeaterGroupingCollection(),
{
	SerializedSetter: function SerializedSetter(value)
	{
		var t = this._properties.Groupings;
		if (t == null || t.length == 0)
		{
			t = new $RepeaterGroupingCollection();
			t.Deserialize(value);
			this.set_Groupings(t);
		}
		else
		{
			for (var i = 0; i < t.length; ++i)
			{
				t[i].Deserialize(value[i]);
			}
			this._OnGroupingsChanged();
		}
	}
	, Serializable: $RepeaterGroupingCollection
});



$GroupedRepeater.prototype.GetEnabledGroupings = function GetEnabledGroupings()
{
	var t = new Array();

	for (var i = 0; i < this.get_Groupings().length; ++i)
	{
		var grouping = this.get_Groupings()[i];

		if (grouping.get_Enabled())
			t.push(grouping);
	}
	t.sort(function(x, y) { return x.get_Order().CompareTo(y.get_Order()); });
	return t;
}
$GroupedRepeater.prototype.get_Groups = function get_Groups()
{
	return this._groups;
}
$GroupedRepeater.prototype.get_UnusedGroups = function get_UnusedGroups()
{
	return this._unusedGroups;
}
$GroupedRepeater.prototype.get_GroupContainers = function get_GroupContainers()
{
	return this._groupContainers;
}


$GroupedRepeater.prototype.Init = function Init()
{
	this.Repeater.Init.call(this);


	this._groups = new Array();
	this._unusedGroups = new Array();

	this._groupContainers = new Array();
	this._groupContainers.push(this);
}
$GroupedRepeater.prototype.Load = function Load()
{
	this.Repeater.Load.call(this);

}
$GroupedRepeater.prototype._Load_ParseRenderedItems = function _Load_ParseRenderedItems()
{
	if (this.get_Groupings().length > 0)
		this._Load_Groupings();
	else
		this.Repeater._Load_ParseRenderedItems.call(this);
}
$GroupedRepeater.prototype._Load_Groupings = function _Load_Groupings()
{
	var container = this._containerElement;
	if (this.get_Groupings().length > 0)
	{
		this._Load_Groupings_One(this._containerElement, this._groups, 0);
	}
}
$GroupedRepeater.prototype._Load_Groupings_One = function _Load_Groupings_One(containerElement, groups, iGrouping)
{
	var grouping = this.get_Groupings()[iGrouping];
	if (____a)
		grouping = new $GroupedRepeaterGrouping();

	var elements = grouping.GetElements(containerElement);
	for (var i = 0; i < elements.length; ++i)
	{
		var group = new $RepeaterGroup(grouping, i.toString(), this.get_Control(), elements[i]);
		group.Init();
		groups.push(group);
		grouping.get_Groups().push(group);

		if (iGrouping < this.get_Groupings().length - 1)
		{
			this._Load_Groupings_One(group.get_ContainerElement(), group.get_Groups(), iGrouping + 1);
		}
		else
		{
			var items = this._GetRenderedItems(group.get_ContainerElement());
			group.get_Items().AddRange(items);
			this._items.AddRange(items);
		}
	}
}
$GroupedRepeater.prototype._OnGroupingsChanged = function _OnGroupingsChanged()
{
	this.RaiseEvent("GroupingsChanged");

	var gs = this.get_Groupings(), gl = gs.length;
	for (var i = 0; i < gl; ++i)
	{
		var g = gs[i];
		if (____a)
			g = new $GroupedRepeaterGrouping();

		g.get_GroupTemplate()._ProcessMarkupAndScript(this.get_Control());
	}

	if (!this._firstValueSet)
	{
		this.UpdateDisplay();
		this.UpdatePages(false);
	}
}
$GroupedRepeater.prototype._DisplayItems_Perform = function _DisplayItems_Perform(displayStart, displayEnd)
{
	if (this.GetEnabledGroupings().length == 0)
	{
		this.Repeater._DisplayItems_Perform.call(this, displayStart, displayEnd);
	}
	else
	{
		this._DisplayItems_Grouped(displayStart, displayEnd);
	}

}
$GroupedRepeater.prototype._DisplayItems_Reset = function _DisplayItems_Reset()
{
	for (var iGroupContainer = 0; iGroupContainer < this._groupContainers.length; ++iGroupContainer)
	{
		var groupContainer = this._groupContainers[iGroupContainer];

		groupContainer.Reset();
	}
}
$GroupedRepeater.prototype._DisplayItems_CleanUp = function _DisplayItems_CleanUp()
{
	for (var iGroupContainer = 0; iGroupContainer < this._groupContainers.length; ++iGroupContainer)
	{
		var groupContainer = this._groupContainers[iGroupContainer];

		groupContainer.CleanUp();
	}
}

$GroupedRepeater.prototype._DisplayItems_Grouped = function _DisplayItems_Grouped(displayStart, displayEnd)
{
	// for each entry (we want to do the whole thing in a single pass)
	for (var iEntry = displayStart; iEntry < displayEnd; ++iEntry)
	{
		this._DisplayItems_OneGroup(this, iEntry, 0);
	}

	// bind all groups recursively
	for (var iGroup = 0; iGroup < this.get_Groups().length; ++iGroup)
	{
		var group = this.get_Groups()[iGroup];

		group.Bind();
	}
}
$GroupedRepeater.prototype._DisplayItems_OneGroup = function _DisplayItems_OneGroup(groupContainer, iEntry, iGrouping)
{
	var entry = this.get_Entries()[iEntry];
	var grouping = this.GetEnabledGroupings()[iGrouping];

	if (____a)
	{
		groups = new Array();
		grouping = new $GroupedRepeaterGrouping();
		groupContainer = new $IGroupedRepeaterGroupContainer();
	}

	// try to find a group which matches this entry
	var existing = this._DisplayItems_OneGroup_Existing(groupContainer.get_Groups(), entry, grouping);

	if (existing == null)
	{// if not, lease new one
		existing = grouping.LeaseGroup(this, groupContainer);
	}
	if (____a)
		existing = new $RepeaterGroup();

	// add the entry to that group. we add entries on every level (as opposed to items which are only displayed on the final level)
	existing.get_Entries().push(entry);


	if (iGrouping < this.GetEnabledGroupings().length - 1) // not final group yet?
	{ // go to next level
		this._DisplayItems_OneGroup(existing, iEntry, iGrouping + 1);
	}
	else
	{ // ok final level, display the item in this group
		existing.DisplayEntry(this, iEntry);
	}
}
$GroupedRepeater.prototype._DisplayItems_OneGroup_Existing = function _DisplayItems_OneGroup_Existing(groups, entry, grouping)
{
	for (var iGroup = 0; iGroup < groups.length; ++iGroup)
	{
		var group = groups[iGroup];
		if (____a)
		{
			group = new $RepeaterGroup();
		}

		if (group.get_Entries().length > 0)
		{
			if (grouping.EntriesEqual(entry, group.get_Entries()[0]))
			{
				return group;
			}
		}
	}
	return null;
}
$GroupedRepeater.prototype._LeaseItem = function _LeaseItem(type, refItem)
{
	return this._LeaseItemGrouped(type, refItem, this);
}
$GroupedRepeater.prototype._LeaseItemGrouped = function _LeaseItemGrouped(type, refItem, preferredGroupContainer)
{
	if (____a) preferredGroupContainer = new $IRepeaterGroupContainer();

	var fn = function(k) { return k.get_Type() == type; };

	var item = preferredGroupContainer.get_UnusedItems().First(fn);
	if (____a) item = new $RepeaterItem();

	if (item != null)
	{
		preferredGroupContainer.get_UnusedItems().Remove(item);
		if (!item.get_Visible())
		{
			item.Show(preferredGroupContainer.get_ContainerElement(), refItem);
		}
	}
	else
	{
		var gc = this.get_GroupContainers(), gcl = gc.length;
		for (var iGroupContainer = 0; iGroupContainer < gcl; ++iGroupContainer)
		{
			var groupContainer = gc[iGroupContainer];
			if (groupContainer != preferredGroupContainer)
			{
				item = groupContainer.get_UnusedItems().First(fn);
				if (item != null)
				{
					groupContainer.get_UnusedItems().Remove(item);
					break;
				}
			}
		}

		if (item == null)
		{
			item = this._CreateNewItem(type);
		}
		item.Show(preferredGroupContainer.get_ContainerElement(), refItem);
	}

	preferredGroupContainer.get_Items().push(item);

	return item;
}
